package com.rock.app.jwt;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.rock.app.base.OpenControllerBase;

import cn.hutool.core.util.StrUtil;

public class JwtInterceptor implements Interceptor {

    public static final String ISUUED_AT = "isuuedAt";

    @Override
    public void intercept(Invocation inv) {
        if (!JwtManager.me().getConfig().isConfigOk()) {
            inv.invoke();
            return;
        }

        HttpServletRequest request = inv.getController().getRequest();
        String token = request.getHeader(JwtManager.me().getHttpHeaderName());

        if (StrUtil.isBlank(token) && StrUtil.isNotBlank(JwtManager.me().getHttpParameterKey())) {
            token = request.getParameter(JwtManager.me().getHttpParameterKey());
        }

        if (StrUtil.isBlank(token)) {
            try {
				processInvoke(inv, null);
			} catch (Exception e) {
				e.printStackTrace();
			}
            return;
        }

        Map map = JwtManager.me().parseJwtToken(token);
        if (map == null) {
            try {
				processInvoke(inv, null);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            return;
        }

        try {
            JwtManager.me().holdJwts(map);
            try {
				processInvoke(inv, map);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        } finally {
            JwtManager.me().releaseJwts();
        }
    }


    private void processInvoke(Invocation inv, Map oldData) throws Exception {

        inv.invoke();


        if (!(inv.getController() instanceof OpenControllerBase)) {
            return;
        }

        OpenControllerBase jbootController = (OpenControllerBase) inv.getController();
        Map<String, Object> jwtMap = jbootController.getJwtAttrs();


        if (jwtMap == null || jwtMap.isEmpty()) {
            refreshIfNecessary(inv, oldData);
            return;
        }

        String token = JwtManager.me().createJwtToken(jwtMap);
        HttpServletResponse response = inv.getController().getResponse();
        response.addHeader(JwtManager.me().getHttpHeaderName(), token);
    }


    private void refreshIfNecessary(Invocation inv, Map oldData) throws Exception {
        if (oldData == null) {
            return;
        }

        // Jwt token 的发布时间
        Long isuuedAtMillis = (Long) oldData.get(ISUUED_AT);
        if (isuuedAtMillis == null || JwtManager.me().getConfig().getValidityPeriod() <= 0) {
            return;
        }

        Long nowMillis = System.currentTimeMillis();
        long savedMillis = nowMillis - isuuedAtMillis;

        if (savedMillis > JwtManager.me().getConfig().getValidityPeriod() / 2) {
            String token = JwtManager.me().createJwtToken(oldData);
            HttpServletResponse response = inv.getController().getResponse();
            response.addHeader(JwtManager.me().getHttpHeaderName(), token);
        }

    }
}
